home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Computer Select (Limited Edition)
/
Computer Select.iso
/
pcmag
/
v10n16
/
pcmfat.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-08-24
|
6KB
|
173 lines
PROGRAM pcmfat;
{*******************************************************************************
* *
* PCMFAT 1.1 Copyright (c) 1991 Barry Simon *
* all rights reserved *
* *
* First Published in PC Magazine, September 10, 1991 *
* *
* Requires Turbo Pascal 6.0 to compile (because of use of inline assembler) *
* *
*******************************************************************************}
{$A-}
{the directive $A- needed StartCluster to line up}
USES DOS, common;
VAR
dta : RECORD
rawdrive : Byte;
unused : ARRAY[0..25] OF Byte; {standard DTA starts at 0}
StartCluster : Word; {to work require $A- directive!}
FSize : LongInt;
END;
FCluster : LongInt;
infcb : ARRAY[0..36] OF Byte;
regs : registers;
s : STRING;
fname : STRING[8];
fext : STRING[3];
i, j : Byte;
NumFATSec, FirstFATSec, InMemSec, CurrentSec, NumCluster : Word;
CurrentCluster, PriorCluster, RecSec, RecOff : Word;
RecShift : Boolean; {determines if first byte is offset in 3 nibble fat}
separator : Char;
NumFrag : Byte;
PROCEDURE SyntaxError;
BEGIN
WriteLn(' Proper syntax is:');
WriteLn(' PCMFAT <filename>');
WriteLn(' where <filename> is in the default drive and directory.');
Halt;
END;
FUNCTION GetRec : Word;
BEGIN
IF Use3NibbleFAT THEN BEGIN
IF RecShift THEN
GetRec := (Word(Sector[RecOff]) DIV 16)+16*Word(Sector[RecOff+1])
ELSE
GetRec := Word(Sector[RecOff])+256*(Word(Sector[RecOff+1]) MOD 16);
END ELSE
GetRec := Word(Sector[RecOff])+256*Word(Sector[RecOff+1]);
END;
PROCEDURE GetLoc;
BEGIN
IF Use3NibbleFAT THEN BEGIN
RecSec := 3*(CurrentCluster DIV 1024)+FirstFATSec;
IF RecSec > NumFATSec THEN BEGIN
WriteLn;
WriteLn('FAT error. Please run chkdsk **without** /f. Program Halted.');
Halt;
END;
RecOff := ((3*(CurrentCluster MOD 1024)) DIV 2);
IF ((RecOff MOD 3) = 0) THEN RecShift := False ELSE RecShift := True;
END ELSE BEGIN
RecSec := Hi(CurrentCluster)+FirstFATSec;
IF RecSec > NumFATSec THEN BEGIN
WriteLn;
WriteLn('FAT error. Please run chkdsk **without** /f. Program Halted.');
Halt;
END;
RecOff := 2*Lo(CurrentCluster);
END;
END;
PROCEDURE GetSector;
BEGIN
CurrentSec := RecSec;
IF NOT(CurrentSec = InMemSec) THEN BEGIN
ReadSector(CurrentSec);
InMemSec := CurrentSec;
END;
END;
BEGIN
WriteLn('PC Magazine''s FAT Reader');
WriteLn(' copyright, Barrry Simon 1991');
IF ParamCount = 0 THEN SyntaxError;
s := ParamStr(1);
IF (pos('\', s)+pos(':', s)) > 0 THEN SyntaxError;
i := pos('.', s);
IF i = 0 THEN BEGIN
s := s+'.';
i := Length(s);
END;
IF i > 9 THEN SyntaxError;
fname := Copy(s, 1, i-1);
Delete(s, 1, i);
IF Length(s) > 3 THEN SyntaxError;
fext := s;
FOR j := 1 TO Length(fname) DO fname[j] := Upcase(fname[j]);
FOR j := 1 TO Length(fext) DO fext[j] := Upcase(fext[j]);
s := fname+'.'+fext;
FOR j := 1 TO (8-Length(fname)) DO fname := fname+' ';
FOR j := 1 TO (3-Length(fext)) DO fext := fext+' ';
FOR i := 1 TO 8 DO infcb[i] := Ord(fname[i]);
FOR i := 9 TO 11 DO infcb[i] := Ord(fext[i-8]);
infcb[0] := 0; {default drive}
WITH regs DO BEGIN
ah := $1A; {set DTA}
ds := Seg(dta);
dx := Ofs(dta);
msdos(regs);
ah := $11;
dx := Ofs(infcb);
ds := Seg(infcb);
msdos(regs);
IF al <> 0 THEN BEGIN
WriteLn(' ', s, ' not found');
SyntaxError;
END;
END;
DriveNum := dta.rawdrive-1; {int 25 and service 11 differ on A=0 or 1, etc}
ReadSector(0);
IF (BootSector.BytesPerSector <> 512) THEN BEGIN
WriteLn(' The sector size isn''t 512 bytes; program halted.');
Halt;
END;
FCluster := ((dta.FSize-1) DIV (512*BootSector.SectorsPerCluster))+1;
WriteLn(' The file ', s, ' has ', FCluster, ' clusters');
WriteLn(' Starting Cluster is ',
HexWord(dta.StartCluster), ' Hex (= ', dta.StartCluster, ' decimal)');
{For display purposes, limit to files with no more than 256 clusters -
that's 512K on a typical hard disk}
IF (FCluster > 256) THEN BEGIN
WriteLn(' This program will only report detailed allotment');
WriteLn(' for files with fewer than 256 clusters. Program halted.');
Halt;
END;
FirstFATSec := BootSector.SectorsBeforeData;
NumFATSec := BootSector.NumSecPerFAT;
asm
mov ah, $1B
push ds
Int $21
pop ds
mov NumCluster, dx
END;
Use3NibbleFAT := (NumCluster < 4097);
{Should read Partition table for totally accurate call}
CurrentCluster := dta.StartCluster;
InMemSec := 0;
NumFrag := 1;
Writeln (' The files occupies clusters (* indicates fragments):' );
Write (' ' , HexWord(CurrentCluster));
for i := 2 to FCluster do begin
GetLoc;
GetSector;
PriorCluster := CurrentCluster;
CurrentCluster := GetRec;
If (CurrentCluster = (PriorCluster + 1)) then separator := ' ' else begin
separator := '*';
inc (NumFrag);
end;
Write (separator,HexWord (CurrentCluster));
end;
Writeln;
Writeln;
Writeln ('The file has ',NumFrag ,' fragments.');
end.